<?
/**
 * gChart.php
 * Defines gChart base class and all Chart type Classes
 * PHP 5
 *
 *
 * @package    gChart
 * @author     Aaron Rubin <aaron@arkitech.net>
 * @copyright  2009 ARKITECH (www.arkitech.net)
 * @version
 *
 */

/**
 	* Google Chart base class, provides base utility methods for all charts.
	* @package gChart
	* @todo - Need to add/update the following:
	* - Styles
	*  - Fill area
	*  - range Markerrs
	*  - financial markers
	* - Charts
	*  - Venn 
	*  - Scatter
	*  - Radar
	*
 */
class gChart {
  /**
   *  @var string base: The base url for the chart API
   */
	var $base = 'http://chart.apis.google.com/chart?';
	/**
   *  @var string encoding: The data encoding type (t: text, s: simple, e: extended) [default: t]
   */
	var $encoding = 't';
	/**
   *  @var int width: Width of the Chart (in pixels) [default: 300]
   */
	var $width = 300;
	/**
   *  @var int height: Height of the Chart (in pixels) [default: 200]
   */
	var $height = 200;
	/**
   *  @var string type: Chart Type [default: lc (Line)]
   */
	var $type = 'lc';
	/**
   *  @var array axes: Container of axes
   */
	var $axes = array();
	/**
   *  @var array colors: Container of colors
   */
	var $colors = array();
	/**
   *  @var array params: Container for parameters
   */
	var $params = array();
	/**
   *  @var int dataMax: The highest value of the data
   */	
	var $dataMax = 0;
	/**
   *  @var int pad: The amount to pad the data
   */	
	var $pad = 0;
	/**
   *  @var bool $useBest: Use the best encoding algorithm (based on the data) [default: true]
   */	
	var $useBest = true;
	/**
   *  @var array $types: Associative array of valid types
   */	
	var $types = array(
		/* LINE CHARTS */
		
		'lc' => 'Data points are spaced evenly along the x-axis.',
		'ls' => 'Sparkline (no Axis by default)',
		'lxy' => 'A pair of data sets is required for each line. The first data set of each pair specifies the x-axis coordinates, and the second data set specifies y-axis coordinates.',
		
		/* Bar Charts */
		'bhs' => 'Horizontal bar chart, with stacked bars',
		'bvs' => 'Vertical bar chart, with stacked bars',
		'bhg' => 'Horizontal bar chart, with grouped bars',
		'bvg' => 'Vertical bar chart, with grouped bars',
		
		/* PIE CHARTS */
		'p'  => 'Two dimensional pie chart',
		'p3' => 'Three dimensional pie chart',
		'pc' => 'Concentric pie charts.',
		
		'v' => 'Venn Diagram',
		
		's' => 'Scatter Plot',
		
		'r'  => 'Radar',
		'rs' => 'Radar with Spline Connectors',
		
		't' => 'Map',
		'qr' => 'QR Codes',
	);
	
	
	/**
   * Constructor function
   *
   */
	public function __construct() {
	
	}
	
	/**
   * Checks colors for html encoding (#XXXXXX) and removes the # 
   * @param string $color The color to check / clean
   * @returns string $color
   */
	private function _cleanColor($color) {
		return ereg_replace('#','',$color);
	}
	
	/**
   * Checks input for standard format, and url encodes
   * @param array $input The input to clean
   * @returns array $cleanInput
   */
	function _cleanInput($input) {
		if (!is_array($input)) $input = array($input);
		foreach ( $input as $i ) {
			$cleanInput[] = urlencode($i);
		}
		return $cleanInput;
	}
	
	/**
   * Performs the SimpleEncoding algorithm to encode data
   * Good for values of 0-61, scales the data with $max, 
   * if no max is given will use max of the values
   * @param array $values The values to encode
   * @param int $max The maximum value
   * @returns string $encoded Encoded data
   */
	public function _simpleEncode($values,$max=61) {
		$simpleEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
		if (!is_array($values)) $values = array($values);
		if (! $max ) $max = max($values);
		$chartData = array();
	  foreach ( $values as $currentValue ) {
	    if ($currentValue >= 0) {
	    	$chartData[] = substr($simpleEncoding,round(61 * $currentValue / $max),1);
	    } else {
	      $chartData[] = '_';
	    }
	  }
		$encoded = join('',$chartData);
		return $encoded;
	}
	
	/**
   * Performs the ExtendedEncoding algorithm to encode data
   * Good for values of 0-4095
   * @param array $values The values to encode
   * @returns string $encoded Encoded data
   */
	public function _extendedEncode($values) {
		$extendedEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-';
		if (!is_array($values)) $values = array($values);
		foreach ( $values as $currentValue ) {
	    if ($currentValue >= 0) {
	    	$fletNum = floor($currentValue/64);
	    	$sletNum = $currentValue%64;
	    	$chartData[] = substr($extendedEncoding,$fletNum,1).substr($extendedEncoding,$sletNum,1);
	    } else {
	      $chartData[] = '__';
	    }
	  }
		$encoded = join('',$chartData);
		return $encoded;
	}
	
	/**
   * Perform the encoding function on the data, and return the encoded result
   * @param array $data The data to encode
   * @returns string $encoded Encoded data
   */	
	function _encodeData($data) {
		switch($this->encoding) {
			case 's': return $this->_simpleEncode($data,$this->dataMax);
			case 'e': return $this->_extendedEncode($data);
			default: return join(',',$data);
		}
	}
	
	/**
   * Adds a parameter to the $params container
 	 * If param already exists will add an additional value to the parameter 
 	 * @see _setParam
   * @param string $param The parameter name
   * @param mixed $val The value of the parameter
   */	
	function _addParam($param,$val) {
		if ( $this->params[$param] ) {
			if (is_array($this->params[$param])) {
				$this->params[$param][] = $val;
			} else {
				$this->params[$param] = array($this->params[$param]);
				$this->params[$param][] = $val;
			}
		} else {
			$this->params[$param] = $val;
		}
	}
	
	/**
   * Sets a parameter to the $params container
 	 * This will overwrite any existing values for this parameter
 	 * @see _addParam
   * @param string $param The parameter name
   * @param mixed $val The value of the parameter
   */
	function _setParam($param,$val) {
			$this->params[$param][] = $val;
	}
	
	/**
   * Add a raw set of data to the dataset container<br>
 	 * Also gets the max value from the dataset and updates $dataMax if it is greater
   * @param array $set Array of values
   */
	function addDataSet($set) {
		$this->datasets[] = $set;
		$max = max($set);
		if ($max > $this->dataMax) $this->dataMax = $max;
	}
	
	/**
   * Create a new Axis object, and add it to the axes container
	 * @see gAxis
   */
	function addAxis($axis,$labels=array(),$positions=array()) {
		$index = count($this->axes);
		$this->axes[] = new gAxis($index,$axis,$labels,$positions);
	}	
	
	/**
   * Add markers to a data set (bar, line, radar, and scatter charts)
	 * @param int $dset The index of the dataset to apply markers to (0 = first data set, 1 = second...)
	 * @param string $type The type of marker (see below for valid types) [default: o]
	 * {@source 1 12} 
	 * is the source
	 * @param string $color The color of the marker
	 * @param int|string $dp The index of the datapoint to add the marker to [default: -1]<ul>
	 * <li>-1 to draw a marker on each data point.
	 * <li>-n to draw a marker on every n-th data point
	 * <li>x:y:n to draw a marker on every n-th data point in a range, where x is the first data point in the range, and y is the last data point in the range.
	 * <li>x:y to draw a marker at a specific point. Add the at character (@) before the marker type to use this option. Specify the coordinates as floating point values, where 0:0 is the bottom left corner of the chart, 0.5:0.5 is the center of the chart, and 1:1 is the top right corner of the chart. For example, to add a red, 15-pixel diamond to the center of a chart, use @d,FF0000,0,0.5:0.5,15.
	 * <li> n to draw a horizontal line. Specify a floating point number for the location of the line, where 0.0 is the bottom of the chart, and 1.0 is the top of the chart.</ul>
	 * @param int $size The size of the marker in pixels [default: 10]
	 * @param int $priority The priortory of the marker [default: 0]<ul>	 
   */
	function addMarkers($dset=0,$type='o',$color,$dp=-1,$size=10,$priority=0) {
		$types = array(
			'a' => 'creates an arrow.',
			'c' => 'creates a cross.',
			'd' => 'creates a diamond.',
			'o' => 'creates a circle.',
			's' => 'creates a square.',
			'v' => 'creates a vertical line from the x-axis to the data point.',
			'V' => 'creates a vertical line across the chart.',
			'h' => 'creates a horizontal line across the chart.',
			'x' => 'creates an x shape.'
		);
		if (!in_array($type,$types)) $type = 'o';
		$color = $this->_cleanColor($color);
		$this->_addParam('chm',"$type,$color,$dset,$dp,$size,$priority");
	}	
	
	/**
   * Sets the data encoding algorith to use
   * Usually not needed
   * @see useBestEncoding
   * @param string $encode - The data encoding to use (t: text, s: simple, e: extended) [default: t]
	 */
	function setEncoding($encode) {
		$this->encoding = $encode;
	}
	
	/**
   * Sets the width and height of the chart
   * @param int $width - The width of the chart in pixels
   * @param int $height -The height of the chart in pixels<br>
   * <b>Note:</b>The largest possible area for all charts except maps is 300,000 pixels. As the maximum height or width is 1000 pixels, examples of maximum sizes are 1000x300, 300x1000, 600x500, 500x600, 800x375, and 375x800.
	 */
	function setSize($width,$height) {
		$this->width  = $width;
		$this->height = $height;
	}
	
	/**
   * Manually sets the types of chart - should probably never be used
   * @param string $type - The type of chart
   * @see $types
	 */
	function setType($type) {
		$this->type = $type;
	}
	
	/**
   * Sets the title of the chart - escapes spaces and newlines
   * @param string $title - The title
   * @param string $color - The color the title should be
   * @param int $size - size of the title text in pixels
   * @see $types
	 */
	function setTitle($title,$color='',$size='') {
		$title = preg_replace("/\n/","|",$title);
		$title = preg_replace("/ /","+",$title);
		$this->_addParam('chtt',$title);
		if ( $color ) {
			$color = $this-_cleanColor($color);
			if ( $size ) $color .= ",$size";
			$this->_addParam('chts',$color);	
		}
	}
	
	/**
   * Sets the leged for the chart
   * @param array $legend - An array of labels for the legend
   * @param string $pos - The position of the chart
   *  - 'b' => 'horizontal row, bottom of the chart',
   *  - 't' => 'horizontal row, top of the chart',
   *  - 'bv' => 'vertical row, bottom of the chart',
   *  - 'tv' => 'vertical row, top of the chart',
   *  - 'r' => 'vertical row, right of the chart',
   *  - 'l' => 'vertical row, left of the chart'
	 */
	function setLegend($legend,$pos='r') {
		$positions = array(
			'b' => 'horizontal row, bottom of the chart',
			't' => 'horizontal row, top of the chart',
			'bv' => 'vertical row, bottom of the chart',
			'tv' => 'vertical row, top of the chart',
			'r' => 'vertical row, right of the chart',
			'l' => 'vertical row, left of the chart'
		);		
		$this->_setParam('chdl',join('|',$this->_cleanInput($legend)));
		if (!in_array($pos,$positions)) $pos = 'r';
		$this->_setParam('chdlp',$pos);
	}
	
	/**
   * Sets the labels for the X Axis of the chart
   * @param array $labels - An array of labels 
	 */
	function setLabels($labels) {
		$this->_addParam('chl',join('|',$this->_cleanInput($labels)));	
	}
	
	/**
   * Sets the Margins for the chart
   * @param int $l - Left Margin
   * @param int $r - Right Margin
   * @param int $t - Top Margin
   * @param int $b - Bottom Margin
   * @param int $lw - Legend Width 
   * @param int $lh - Legend Height 
	 */
	function setMargins($l,$r,$t,$b,$lw=null,$lh=null) {
		$margin = "$l,$r,$t,$b";
		if(isset($lw)&&isset($lh)) {
			$margin .= "|$lw,$lh";
		}
		$this->_setParam('chma',$margin);
	
	}
	
	/**
   * Sets the colors for data objects (lines, bars etc) of the chart
   * @param array $colors - An array of colors 
	 */
	function setColors($colors) {
		if (!is_array($colors)) $colors = array($colors);
		foreach ( $colors as $color ) {
			$cleancolors[] = $this->_cleanColor($color);
		}
		$this->colors = $cleancolors;
	}
	
	/**
   * Sets the image background (outside of the chart) color
   * @param string $color - The color to use
	 */
	function setBackgroundColor($color) {
		$color = $this->_cleanColor($color);
		$this->_setParam('chf',"bg,s,$color");
	}
	
	/**
   * Sets the chart background (under the data) color
   * @param string $color - The color to use
	 */
	function setChartColor($color) {
		$color = $this->_cleanColor($color);
		$this->_addParam('chf',"c,s,$color");
	}
	
	/**
   * Sets the grid properties of the chart
   * @param int $xstep - The x axis step size
   * @param int $ystep - The y axis step size   
   * @param int $lseg - The length of the line segment
   * @param int $bseg - The length of the blank segment
   * @param int $xoff - The offset fro the x-axis
   * @param int $yoff - The offset fro the x-axis
	 */
	function setGrid($xstep,$ystep,$lseg=null,$bseg=null,$xoff=null,$yoff=null) {
		$value = "$xstep,$ystep";
		if ( isset($bseg) ) {
			if (!isset($lseg)) $lseg = 1;
			$value .= "$lseg,$bseg";
		}
		if ( isset($yoff) ) {
			if (!isset($xoff)) $xoff = 0;
			$value .= "$xoff,$yoff";
		}
		$this->_addParam('chg',$value);	
	}
	
	/**
		* Set a pad for the data
		* This amount is added to {@link dataMax} before encoding
		* @param int $pad - Amount to pad the data
		*/
	function setPad($pad) {
		$this->pad = $pad;
	}

	/**
		* Auto-select the best labels for the Y-Axis
		* This will figure out accurate lables for your Y-axis by starting from 0 and then adding
		* ({@link dataMax}/steps) for steps times
		* @param int $steps - Number of labels (or steps) to create [default: 6]
		*/
	function useBestYAxis($steps=6) {
		$this->useBestY = $steps;
	}
	
	/**
		* Auto-select the best encoding algorithmf for the data-provides
		*
		* <b>This is enabled by default</b>
		*
		* @param bool $use - Should best encoding be used [default: true]
		*/
	function useBestEncoding($use=true) {
		$this->useBest = $use;
	}
	
	/**
		* Determines the best Y-Axis label representation
	 	*
	 	* If {@link useBestYAxis()} is called, determines the values for the Y-Axis
	 	*/
	function _getBestYAxis() {
		if (!$this->useBestY) return;
		//add idiot proofing
		$steps = array();
		$increment = ceil($this->dataMax/$this->useBestY);
		for ( $step = 0; $step < $this->dataMax; $step += $increment ) {
			$steps[] = $step;
		}
		
		$this->addAxis('y',$steps);	
	}
	
	/**
		* Determines the encoding algorith to use
	 	*
	 	* If {@link useBestEncoding()} is called, determines the best encoding algorithm
	 	*/
	function _getBestEncoding() {
		if ( !$this->useBest ) return;
		if ( $this->dataMax > 100 ) $this->encoding = 'e';
		elseif ( $this->dataMax > 61 ) $this->encoding = 't';
		else $this->encoding = 's';
	}
	
	/**
		* Get the URL encoding for the datasets
	 	*
	 	*/
	function _getURLData() {
		if ($this->pad)	$this->dataMax += $this->pad;
		$this->_getBestEncoding();		
		$data = "chd=$this->encoding:";
		foreach ( $this->datasets as $set ) {
			if ($cnt) {
				switch($this->encoding) {
					case 't': $data .= '|'; break;
					default: $data .= ',';
				}
			}
			$data .= $this->_encodeData($set);					
			$cnt++;
		}  
		return $data;
	}
	
	/**
		* Get the URL encoding for the chart size
	 	*
	 	*/	
	function _getURLSize() {
		return "chs={$this->width}x{$this->height}";
	}

	/**
		* Get the URL encoding for the chart type
	 	*
	 	*/		
	function _getURLType() {
		return "cht=$this->type";
	}
	
	/**
		* Get the URL encoding for the chart colors
	 	*
	 	*/		
	function _getURLColors() {
		return "chco=".join(',',$this->colors);
	}

	/**
		* Get the URL encoding for the chart axes
	 	*
	 	*/		
	function _getURLAxis() {
		$this->_getBestYAxis();
		if ( !$this->axes ) return;
		foreach ( $this->axes as $axis ) {
				$chxt[] = $axis->axis;
				if ($axis->labels) $chxl[] = $axis->getLabels();
		}		
		$this->urlParts[] = 'chxt='.join(',',$chxt);
		if ( $chxl ) $this->urlParts[] = 'chxl='.join('|',$chxl);
	}

	/**
		* Get the URL encoding for all other parameters
	 	*
	 	*/				
	function _getURLParameters() {
		if ( $this->params ) {
			foreach ( $this->params as $param => $value ) {
				if ( is_array($value) ) {
					$this->urlParts[] = "$param=".join('|',$value);
				} else {
					$this->urlParts[] = "$param=$value";
				}
			}
		}
	}
	
	/**
		* Get the full URL for the chart
	 	* @returns string $url - Return the full URL of the chart
	 	*/	
	function getURL() {		
		$this->urlParts = array();
		$this->urlParts[] = $this->_getURLType();	
		$this->urlParts[] = $this->_getURLSize();	
		$this->urlParts[] = $this->_getURLData();	
		if ( $this->colors ) $this->urlParts[] = $this->_getURLColors();
		$this->_getURLParameters();
		$this->_getURLAxis();
		return $this->base.join('&',$this->urlParts);
	}
	
}

/**
 * Google Line Chart Base Class
 *
 * Provides methods for all line-based charts
 * @package gChart
 * @subpackage BaseClass
 */
class gLineChart extends gChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to lc (for line charts)
   */
	function __construct() {
		parent::__construct();
		$this->type = 'lc';
	}

	/**
   * Adds line styles to the chart
   *
   * @param int $thickness - width of the line in pixels
   * @param int $lseg - length of the colored portion of the line
   * @param int $bseg - length of the blank portion of the line
   */
	function addLineStyle($thickness,$lseg=0,$bseg=0) {
		$this->_addParam('chls',"$thickness,$lseg,$bseg");
	}
}


/**
 * Google Pie Chart Base Class
 *
 * Provides methods for all pie-based charts
 * @package gChart
 * @subpackage BaseClass
 */
class gPieChart extends gChart {

	/**
   * Constructor function
   * Sets the chart {@link type} to p (for pie charts)
   */
	function __construct() {
		parent::__construct();
		$this->type = 'p';
	}	
	
	/**
   * Set the pie chart roation
   *
   * Changes the orientation of the pie chart
   * @param int|float $deg - Degrees or radians of the rotation [defaukt: expects degrees]
   * @param bool $rad - The vakue given is in radians
   */
	function setRotation($deg,$rad=false) {
		$rotate = ($rad)?deg2rad($deg):$deg;
		$this->_addParam('chp',$rotate);
	}
}

/**
 * Google 3D Pie Chart Class
 *
 * @package gChart
 * @subpackage UtilityClass
 *
 */
class gPieChart3D extends gPieChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to p3 (for 3D pie charts)
   */
	function __construct() {
		parent::__construct();
		$this->type = 'p3';
	}
}

/**
 * Google Concentric Pie Chart Class
 *
 * @package gChart
 * @subpackage UtilityClass
 *
 */
class gConcentricPieChart extends gPieChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to pc (for concentric pie charts)
   */
	function __construct() {
		parent::__construct();
		$this->type = 'pc';
	}
}

/**
 * Google Bar Chart Base Class
 *
 * Provides methods for all bar-based charts
 * @package gChart
 * @subpackage BaseClass
 */
class gBarChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to bhs (for horizontal bar chart)
   */
	function __construct() {
		parent::__construct();
		$this->type = 'bhs';
	}
	
	/**
		* Set the charts orientation to vertical
		* 
		* @param bool $v - Set to vertical? [default:true];
		*/
	function setVertical($v=true) {
		if ( $v ) ereg_replace('h','v',$this->type);
		else ereg_replace('v','h',$this->type);
	}

	/**
		* Set the chart to auto-figure the width of the bars 
		* 
		* This is done by the charting engine, not the PHP class
		* @param bool $aw - Figure auto-width? [default:true];
		*/
	function setAutoWidth($aw=true) {
		if ( $aw ) $this->_setParam('chbh','a');
	}

	/**
		* Set the chart to auto-figure the space between bars relative to their width
		* 
		* This is done by the charting engine, not the PHP class
		* @param bool $aw - Figure auto-width? [default:true];
		*/
	function setRelativeWidth($aw=true) {
		if ( $rw ) $this->_setParam('chbh','r');
	}

	/**
		* Set the width of the bars, and their spacing
		* 
		* This is done by the charting engine, not the PHP class
		* @param int|string $width - The width of the bars in pixels (use can use a for auto, and r for relative)
		* @param int $barSpace - The space between bars [default: 4]
		* @param int $groupSpace - The space between gorups of bars [default: 8]
		* @todo - Should check if already set Auto or relative width and use that as width
		*/
	function setWidthAndSpace($width,$barSpace=4,$groupSpace=8) {
		$this->_setParam('chbh',"$width,$barSpace,$groupSpace");
	}

}

/**
 * Google Stacked Bar Chart Class
 *
 * @package gChart
 * @subpackage UtilityClass
 *
 */
class gStackedBarChart extends gBarChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to bhs (for stacked horizontal bar chart)
   */
	function __construct() {
		parent::__construct();
		$this->type = 'bhs';
	}	
}

/**
 * Google Grouped Bar Chart Class
 *
 * @package gChart
 * @subpackage UtilityClass
 *
 */
class gGroupedBarChart extends gBarChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to bhg (for grouped horizontal bar chart)
   */
	function __construct() {
		parent::__construct();
		$this->type = 'bhg';
	}	
}

/**
 * Google Map Base Class
 *
 * Provides methods for map charts
 * @package gChart
 * @subpackage BaseClass
 */
class gMapChart extends gChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to t (for map charts)
   */
	function __construct() {
		parent::__construct();
		$this->type = 't';
		$this->setBackgroundColor('EAF7FE');
	}	
	
	/**
   * Sets the area to be shown on the map
   * @param string $area - area to show, options are:
   * - africa
   * - asia
   * - europe
   * - middle_east
   * - south_america
   * - usa
   * - world
   */
	function setArea($area) {
		$areas = array(
			'africa',
			'asia',
			'europe',
			'middle_east',
			'south_america',
			'usa',
			'world'
		);
		
		if (!in_aray($area,$areas)) $area = 'world';
		
		$this->_setParam('chtm',$area);
		
	}
	
	/**
   * Sets the background color (water color) on the map
   * @param string $color - color to use
	 */
	function setWaterColor($color) {
		$this->setBackgroundColor($color);
	}
	
	/**
   * Specifies which contries to correlate to the data
   *
   * Only one of setCountries or {@link setStates} should be used
   * @param array $countries - 2-3 character ISO country codes
	 */
	function setCountries($countries) { 
		$this->_setParam('chld',join('',$countries));
	}

	/**
   * Specifies which states to correlate to the data
   *
	 * Only one of {@link setCountries()} or setStates should be used
   * @param array $states - 2 character ISO state codes
	 */
	function setStates($states) { 
		$this->_setParam('chld',join('',$states));
	}
}

/**
 * Google Meter Base Class
 *
 * Provides methods for meter charts
 * @package gChart
 * @subpackage BaseClass
 */
class gMeter extends gChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to gom (for google meter charts)
   */
	function __construct() {
		parent::__construct();
		$this->type = 'gom';
	}	
}

/**
 * Google QR Base Class
 *
 * Provides methods for QR charts
 * @package gChart
 * @subpackage BaseClass
 */
class gQR extends gChart {
	/**
   * Constructor function
   * Sets the chart {@link type} to qr (for google qr charts)
   */
	function __construct($text='',$encoding='') {
		parent::__construct();
		$this->type = 'qr';
		if ( $text ) $this->setText($text);
		if ( $encoding ) $this->setEncoding($encoding);		
	}	
	
	/**
   * Sets the text of the QR
   * 
   * @param string $text - The raw text to be encoded in the QR code
   */
	function setText($text) {
		$this->_setParam('chl',$area);
	}
	
	/**
   * Sets the text encoding of the QR
   * 
   * @param string $encode - The text-encoding of the text [default: UTF-8]
   * Valid values are:
   * - Shift_JIS
   * - UTF
   * - ISO-8859-1
   */
	function setTextEncoding($encode) {
		$encodings = array(
			'Shift_JIS', 
			'UTF-8', 
			'ISO-8859-1'
		);
		if (!in_array($encode,$encodings)) $encode = 'UTF-8';
		
		$this->_setParam('choe',$encode);
	}
	
	/**
   * Sets the Error Correction Level of the QR
   * 
   * @param string $level - The level or error correction ((L)ow 7%, (M)edium 15%, (Q)uarter 25%, (H)igh 30%)
   * @param string $margin - The margin or blank space around QR code in pixels [default: 4] 
   */
	function setECLevel($level,$margin=4) {
		$levels = array('L','M','H','Q');
		if (!in_array($levels,$levels)) $level = 'L';
		$this->_setParam('chld',"$level|$margin");		
	}
	
}

/**
	* Base Class for Building Axes for Google Charts
  * 
	* @package gChart
	* Provides methods for map charts
	* @todo - Needs updates
	*  - Fixes
	*   - add axis positioning
	*   - add axis range
	*   - add axis styles
	* - Probably does not need to subclass gChart (except for use of {@link cleanInput()}
	* @subpackage BaseClass	
 */
class gAxis extends gChart {
	var $index;
	var $axis;
	var $labels;
	var $positions;
	
	function __construct($index,$axis,$labels=array(),$positions=array()) {
		$this->index  		= $index;
		$this->axis   		= $axis;
		$this->labels 		= $labels;
		$this->positions 	= $positions;
	}

	function getLabels() {
		return "$this->index:|".join('|',$this->_cleanInput($this->labels));
	}

}




?>